package com.xhwl.centiotdata.suppliersystem.eesd.growatt;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.xhwl.centiotdata.constant.EesdConstant;
import com.xhwl.centiotdata.handler.alarm.impl.AlarmIStartIotMaxHandle;
import com.xhwl.centiotdata.pojo.enums.device.DeviceProductCategoryEnum;
import com.xhwl.centiotdata.pojo.enums.eesd.EesdMethodEnum;
import com.xhwl.centiotdata.service.cent.IDeviceCentService;
import com.xhwl.centiotdata.service.integrateconfig.EESDSupplierConfig;
import com.xhwl.centiotdata.utils.RedisUtils;
import com.xhwl.centiotdata.utils.StrUtils;
import com.xhwl.common.dto.cent.device.DeviceDTO;
import com.xhwl.common.dto.cent.eesd.PhotovoltaicsSeriesDTO;
import com.xhwl.common.dto.cent.iotdata.growatt.*;
import com.xhwl.common.enums.device.DeviceTypeEnum;
import com.xhwl.common.pojo.ResultJson;
import com.xhwl.common.pojo.cent.device.DeviceProjSupplierCategory;
import com.xhwl.common.vo.cent.eesd.PhotovoltaicsSeriesVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestPart;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @Author： lianghz
 * @Description：
 * @Date 2021/09/03/ 09:44
 */
@Slf4j
@RestController
public class GrowattApiHandler {

    @Resource
    private GrowattUtil growattUtil;
    @Autowired
    private EESDSupplierConfig supplierConfig;
    @Resource
    private RedisUtils redisUtils;
    @Autowired
    private IDeviceCentService centService;
    @Autowired
    private AlarmIStartIotMaxHandle alarmIStartIotMaxHandle;

    /**
     * 查询光伏组串电压电流
     */
    @PostMapping(value = "/photovoltaics/series")
    public ResultJson getSeries(@RequestPart("dto") PhotovoltaicsSeriesDTO dto) {
        String key = EesdConstant.SERIES + dto.getProjectId() + ":" + dto.getSeries();
        Object o = redisUtils.get(key);
        if (o == null) {
            List<PhotovoltaicsSeriesVO> series = getSeries(dto.getProjectId(), dto.getSeries());
            if (!CollectionUtils.isEmpty(series)) {
                redisUtils.setWithMinute(key, series, 8);
            }
        }
        Object o1 = redisUtils.get(key);
        if (o1 == null) {
            return ResultJson.fail("查询光伏组串电压电流失败");
        }
        List<PhotovoltaicsSeriesVO> list = JSONObject.parseArray(JSON.toJSONString(o1), PhotovoltaicsSeriesVO.class);

        return ResultJson.success(list);
    }

    /**
     * 获取组串电流电压
     * 获取电流电压数据
     * @return
     */
    public List<PhotovoltaicsSeriesVO> getSeries(Integer projectId, int series) {
        List<PhotovoltaicsSeriesVO> list = new ArrayList<>();
        Integer productId = EesdMethodEnum.GROWATT.getId();
        String key = projectId + EesdConstant.EESD_UNDERSCORE +
                productId +EesdConstant.EESD_UNDERSCORE + EesdConstant.EESD_CONFIG;

        Object o = redisUtils.get(key);
        if (o == null) {
            List<DeviceProjSupplierCategory> configList =
                    supplierConfig.getIntegrationConfig(DeviceProductCategoryEnum.EESD.getId());
            configList = configList.stream().filter(d -> d.getProductId().equals(productId)
                    && d.getProjectId().equals(projectId)).collect(Collectors.toList());
            if (CollectionUtils.isEmpty(configList) && configList.size() > 1) {
                throw new RuntimeException("运管平台：该项目光伏配置异常");
            }
            DeviceProjSupplierCategory deviceProjSupplierCategory = configList.get(0);
            // 存储到redis  key:project_productId_eesd_config  value:配置
            redisUtils.setWithMinute(key, deviceProjSupplierCategory, EesdConstant.FIFTEEN_MINUTE);
        }
        DeviceProjSupplierCategory dto = (DeviceProjSupplierCategory) redisUtils.get(key);
        try {
            JSONObject properties = dto.getProperties();
            GrowattReqConfigDTO config = JSONObject.parseObject(properties.toJSONString(), GrowattReqConfigDTO.class);

            GrowattDataRespDTO inverterRealTime = growattUtil.getInverterRealTime(config);
            if (!ObjectUtils.isEmpty(inverterRealTime)) {
                for (int i = 1; i < series + 1; i++) {
                    PhotovoltaicsSeriesVO resp = new PhotovoltaicsSeriesVO();
                    String aName = EesdConstant.GROWATT_A + i;
                    String vName = EesdConstant.GROWATT_V + i;
                    resp.setSeriesNum(i);
                    String v = getValue(inverterRealTime, vName);
                    if (ObjectUtils.isEmpty(v)) {
                        resp.setV(new BigDecimal("0.00"));
                    } else {
                        resp.setV(new BigDecimal(v).setScale(2,BigDecimal.ROUND_FLOOR));
                    }
                    String a = getValue(inverterRealTime, aName);
                    if (ObjectUtils.isEmpty(a)) {
                        resp.setA(new BigDecimal("0.00"));
                    } else {
                        resp.setA(new BigDecimal(a).setScale(2,BigDecimal.ROUND_FLOOR));
                    }
                    list.add(resp);
                }
                log.info("Get series data:  {}", JSON.toJSONString(list));
            }
        } catch (Exception e) {
            log.error("Failed to get series data: {}", e.getMessage());
        }
        return list;
    }

    /**
     * 动态获取字段值
     * @param dto
     * @param name get字段名
     * @return
     */
    public static String getValue(GrowattDataRespDTO dto, String name) {
        try {
            Method m = GrowattDataRespDTO.class.getDeclaredMethod(name);
            return (String) m.invoke(dto);
        } catch (Exception e) {
            log.error("Failed to get field value dynamically：{}", e.getMessage());
        }
        return null;
    }

    /**
     * 获取电站数据
     * @return
     * 日、月、年、累计发电量
     * 总有功功率
     */
    public OdsPhotovoltaicsMetricsDTO getPlantInfo(GrowattReqConfigDTO dto, Integer deviceType) {
        OdsPhotovoltaicsMetricsDTO resp = new OdsPhotovoltaicsMetricsDTO();
        try {
            GrowattDataRespDTO planData = growattUtil.getPlanData(dto);
            /*String json = ReadJsonUtils.getJson("Plant.json");
            GrowattDataRespDTO planData = JSONObject.parseObject(json, GrowattDataRespDTO.class);*/

            if (!ObjectUtils.isEmpty(planData)) {
                resp.setProjectId(dto.getProjectId());
                resp.setProductId(dto.getProductId());
                resp.setType(deviceType);
                resp.setThirdDeviceId(dto.getProjectId() + deviceType.toString());
                resp.setCapacity(StrUtils.strCoverBD(dto.getCapacity()));
                resp.setModulus(StrUtils.strCoverBD(dto.getModulus()));
                // 日、月、年、累计发电量
                resp.setTodayPower(StrUtils.strCoverBD(planData.getToday_energy()));
                resp.setMonthPower(StrUtils.strCoverBD(planData.getMonthly_energy()));
                resp.setYearPower(StrUtils.strCoverBD(planData.getYearly_energy()));
                resp.setTotalPower(StrUtils.strCoverBD(planData.getTotal_energy()));
                // 当前功率（kW） 实时功率
                resp.setOutputPower(StrUtils.strCoverBD(planData.getCurrent_power()));
            } else {
                resp = null;
            }
        } catch (Exception e) {
            log.error("Failed to get power station data:{}", e.getMessage());
            resp = null;
        }
        return resp;
    }

    /**
     * 获取逆变器数据
     * @return
     */
    public OdsPhotovoltaicsMetricsDTO getInverterInfo(GrowattReqConfigDTO dto, Integer deviceType) {
        OdsPhotovoltaicsMetricsDTO resp = new OdsPhotovoltaicsMetricsDTO();
        try {
            GrowattDataRespDTO inverterRealTime = growattUtil.getInverterRealTime(dto);
            int alarm = 0;
            try {
                alarm = growattUtil.getInverterAlarm(dto).getCount();
                if (alarm > 0) {
                    alarmIStartIotMaxHandle.maxInfoReceive(growattUtil.getInverterAlarm(dto).toString(), dto.getProjectId());
                }
            } catch (Exception e) {
                log.error("获取逆变器数据异常：{}", e.getMessage());
            }
            if (!ObjectUtils.isEmpty(inverterRealTime)) {
                resp.setAlarmCount(alarm);
                resp.setProjectId(dto.getProjectId());
                resp.setProductId(dto.getProductId());
                resp.setType(deviceType);
                resp.setThirdDeviceId(dto.getProjectId() + deviceType.toString());
                resp.setCapacity(StrUtils.strCoverBD(dto.getCapacity()));
                resp.setModulus(StrUtils.strCoverBD(dto.getModulus()));
                BigDecimal pac = StrUtils.strCoverBD(inverterRealTime.getPac());
                BigDecimal outputPower;
                if (pac.compareTo(BigDecimal.ZERO) == 0) {
                    outputPower = BigDecimal.ZERO;
                } else {
                    outputPower = pac.divide(StrUtils.strCoverBD("1000")).setScale(2, RoundingMode.HALF_UP);
                }
                BigDecimal reactive = StrUtils.strCoverBD(inverterRealTime.getRac());
                BigDecimal reactivePower;
                if (reactive.compareTo(BigDecimal.ZERO) == 0) {
                    reactivePower = BigDecimal.ZERO;
                } else {
                    reactivePower = reactive.divide(StrUtils.strCoverBD("1000")).setScale(2, RoundingMode.HALF_UP);
                }
                BigDecimal power = StrUtils.strCoverBD(inverterRealTime.getPowerToday());
                BigDecimal todayPower;
                if (power.compareTo(BigDecimal.ZERO) == 0) {
                    todayPower = BigDecimal.ZERO;
                } else {
                    todayPower = power.divide(StrUtils.strCoverBD("1000")).setScale(2, RoundingMode.HALF_UP);
                }
                // 总有功功率
                resp.setOutputPower(outputPower);
                // 无功功率
                resp.setReactivePower(reactivePower);
                // 功率因素
                resp.setPowerFactor(StrUtils.strCoverBD(inverterRealTime.getPf()));
                // 电网频率
                resp.setFrequency(StrUtils.strCoverBD(inverterRealTime.getFac()));
                resp.setTemp(StrUtils.strCoverBD(inverterRealTime.getTemperature()));
                resp.setTimeTotal(StrUtils.strCoverBD(inverterRealTime.getTimeTotal()));
                resp.setV1(StrUtils.strCoverBD(inverterRealTime.getVacr()));
                resp.setV2(StrUtils.strCoverBD(inverterRealTime.getVacs()));
                resp.setV3(StrUtils.strCoverBD(inverterRealTime.getVact()));
                resp.setA1(StrUtils.strCoverBD(inverterRealTime.getIacr()));
                resp.setA2(StrUtils.strCoverBD(inverterRealTime.getIacs()));
                resp.setA3(StrUtils.strCoverBD(inverterRealTime.getIact()));
                //  当天发电量(发电量趋势)
                resp.setTodayPower(todayPower);
            } else {
                resp = null;
            }
        } catch (Exception e) {
            log.error("Failed to get inverter data data:{}", e.getMessage());
            resp = null;
        }
        return resp;
    }

    /**
     * 环境检测仪数据
     */
    public OdsPhotovoltaicsMetricsDTO getEnvInfo(GrowattReqConfigDTO dto, Integer deviceType) {
        OdsPhotovoltaicsMetricsDTO resp = new OdsPhotovoltaicsMetricsDTO();
        try {
            /*String json = ReadJsonUtils.getJson("env.json");
            GrowattEnvRespDTO envRealTime = JSONObject.parseObject(json, GrowattEnvRespDTO.class);*/
            GrowattEnvRespDTO envRealTime = growattUtil.getEnvRealTime(dto);
            // 累计辐照度
            String totalRadiant = growattUtil.getTotalRadiant(dto);
            if (StringUtils.isEmpty(totalRadiant)) {
                totalRadiant = EesdConstant.NUM_0_STR_2;
            }
            if (!ObjectUtils.isEmpty(envRealTime)) {
                resp.setType(deviceType);
                resp.setProductId(dto.getProductId());
                resp.setProjectId(dto.getProjectId());
                resp.setThirdDeviceId(dto.getProjectId() + deviceType.toString());
                resp.setCapacity(StrUtils.strCoverBD(dto.getCapacity()));
                resp.setModulus(StrUtils.strCoverBD(dto.getModulus()));
                resp.setCumulativeRadiant(StrUtils.strCoverBD(totalRadiant));

                resp.setTemp(StrUtils.strCoverBD(envRealTime.getEnvTemp()));
                resp.setHumidity(StrUtils.strCoverBD(envRealTime.getEnvHumidity()));
                resp.setRadiant(StrUtils.strCoverBD(envRealTime.getRadiant()));
                resp.setWindDir(envRealTime.getWindAngle());
                resp.setWindSpeed(StrUtils.strCoverBD(envRealTime.getWindSpeed()));
            } else {
                resp = null;
            }
        } catch (Exception e) {
            log.error("Failed to get weather station data:{}", e.getMessage());
            resp = null;
        }
        return resp;
    }

    //同步max设备
    public ResultJson syncMaxDevice(@RequestBody GrowattReqConfigDTO dto){
        List<GrowattDeviceRespDTO> deviceList = growattUtil.getDeviceList(dto);
        List<DeviceDTO> deviceDTOList = new ArrayList<>();
        deviceList.forEach(e->{
            DeviceDTO deviceDTO = new DeviceDTO();
            deviceDTO.setThirdDeviceId(e.getDevice_sn());
            deviceDTO.setOnlineStatus(e.getStatus());
            deviceDTO.setProductId(dto.getProductId());
            deviceDTO.setProjectId(dto.getProjectId());
            deviceDTO.setDeviceTypeId(66);
            deviceDTO.setName("光伏MAX");
            deviceDTOList.add(deviceDTO);
        });
       return centService.asyncUpdateDevice(deviceDTOList);
    }
}
